<template>
    <div class="chat-content">
        <div
            class="chat-messages"
            ref="chatMessagesRef"
            :style="{ maxHeight: chatMessagesMaxHeight + 'px' }"
            @scroll="onScroll"
        >
            <div v-for="(message, index) in chatMessages" :key="index">
                <!-- 判断消息类型，分别渲染用户消息和大模型回复的消息 -->
                <div v-if="message.role === 'user'" class="user-message">
                    <div class="message-header">
                        <img src="@/assets/img/user.png" alt="头像" class="avatar" />
                        <span class="sender-label">你：</span>
                    </div>
                    <div class="message-bubble" v-html="parseMarkdown(message.content)"></div>
                </div>
                <div v-else-if="message.role === 'assistant'" class="model-message">
                    <div class="message-header">
                        <img src="@/assets/img/model.png" alt="模型头像" class="avatar" />
                        <span class="sender-label">{{select_model}} 大模型：</span>
                    </div>
                    <div class="message-bubble markdown-body" v-html="parseMarkdown(message.content)"></div>
                </div>
            </div>
        </div>
        <div class="chat-input" ref="chatInputRef">
            <input
                :value="inputMessage"
                @input="handleInput"
                @keyup.enter="sendMessage"
                placeholder="输入消息..."
            />
            <button @click="sendMessage">发送</button>
        </div>
    </div>
</template>

<script setup>
import {
    ref,
    defineProps,
    defineEmits,
    onMounted,
    watch,
    nextTick
} from 'vue';
import { parse } from 'marked';
import { useApiStore } from '../store/api';
// 引入github-markdown-css样式
import 'github-markdown-css/github-markdown-light.css';

const props = defineProps({
    chatMessages: {
        type: Array,
        default: () => []
    },
    inputMessage: {
        type: String,
        default: ''
    },
    windowWidth: {
        type: Number,
        default: 400
    },
    chatMessagesMaxHeight: {
        type: Number,
        default: 0
    }
});

const apiStore = useApiStore();
const select_model = apiStore.appKeyInfo.select_model;

const emits = defineEmits([
    'sendInputHeight',
    'sendMessage',
    'update:inputMessage'
]);

const chatMessagesRef = ref(null);
const chatInputRef = ref(null);
const isUserScrolling = ref(false);

const handleInput = (event) => {
    emits('update:inputMessage', event.target.value);
};

const sendMessage = () => {
    // 将用户消息封装成包含 role 和 content 的对象
    const userMessage = {
        role: 'user',
        content: props.inputMessage
    };
    const modelMessage = {
        role: 'assistant',
        content: '正在思考中...'
    };
    emits('sendMessage', userMessage);
    emits('sendMessage', modelMessage);
    // 清空输入框内容
    emits('update:inputMessage', '');
    nextTick(() => {
        if (chatMessagesRef.value && !isUserScrolling.value) {
            chatMessagesRef.value.scrollTop = chatMessagesRef.value.scrollHeight;
        }
    });
};

const sendInputHeight = () => {
    if (chatInputRef.value) {
        emits('sendInputHeight', chatInputRef.value.offsetHeight);
    }
};

// 处理滚动事件
const onScroll = () => {
    isUserScrolling.value = true;
    // 当滚动停止一段时间后，允许自动滚动恢复
    clearTimeout(window.scrollTimer);
    window.scrollTimer = setTimeout(() => {
        isUserScrolling.value = false;
    }, 500); // 500ms 可根据需要调整
};

// 监听消息数组变化
watch(() => props.chatMessages, () => {
    nextTick(() => {
        if (chatMessagesRef.value && !isUserScrolling.value) {
            chatMessagesRef.value.scrollTop = chatMessagesRef.value.scrollHeight;
        }
    });
}, { deep: true });

onMounted(() => {
    sendInputHeight();
});

watch(
    () => props.windowWidth,
    () => {
        sendInputHeight();
    }
);

// 解析 Markdown 语法
const parseMarkdown = (message) => {
    // 检查是否包含 <think> 标签
    const thinkStartIndex = message.indexOf('<think>');
    const thinkEndIndex = message.indexOf('</think>');

    if (thinkStartIndex !== -1 && thinkEndIndex !== -1) {
        // 提取 <think> 标签及其内容
        const thinkContent = message.slice(thinkStartIndex, thinkEndIndex + '</think>'.length);
        // 提取 <think> 标签之后的内容
        const markdownContent = message.slice(thinkEndIndex + '</think>'.length);
        // 解析 Markdown 内容
        const parsedMarkdown = parse(markdownContent);
        // 返回拼接后的内容
        return `${thinkContent}${parsedMarkdown}`;
    }

    // 如果没有 <think> 标签，直接解析整个消息
    return parse(message);
};
</script>

<style scoped>
.chat-content {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.chat-messages {
    flex: 1;
    padding: 10px;
    overflow-y: auto;
    background-color: white;
}

.chat-input {
    display: flex;
    padding: 10px;
    border-top: 1px solid #ccc;
    background-color: white;
}

.chat-input input {
    flex: 1;
    padding: 5px;
    margin-right: 10px;
}

.user-message {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    margin-bottom: 10px;
}

.model-message {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    margin-bottom: 10px;
}

.message-header {
    display: flex;
    align-items: center;
}

.avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    margin-right: 5px;
}

.sender-label {
    font-weight: bold;
}

.message-bubble {
    background-color: white;
    border: 1px solid gray;
    padding: 10px;
    border-radius: 10px;
    margin-top: 5px;
    max-width: 100%;
    word-wrap: break-word;
    display: flex;
    flex-direction: column;
}

/* 为了让github-markdown-css样式在message-bubble内生效 */
.markdown-body >>> pre {
    background-color: black;
}

.markdown-body >>> pre code {
    color: white;
}

/* 自定义 <think> 标签样式 */
.markdown-body >>> think {
    background-color: #EFEFEF;
    font-size: 14px;
    padding: 5px;
    border-radius: 4px;
    color: #979797;
}
</style>